package com.kaibes.im.model;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

import org.json.JSONArray;
import org.json.JSONException;
import org.json.JSONObject;

import android.annotation.SuppressLint;
import android.app.ActivityManager;
import android.app.ActivityManager.RunningAppProcessInfo;
import android.app.Notification;
import android.app.PendingIntent;
import android.content.Context;
import android.content.SharedPreferences.Editor;
import android.database.Cursor;
import android.graphics.BitmapFactory;
import android.net.Uri;
import android.support.v4.app.NotificationCompat;
import android.support.v4.app.NotificationManagerCompat;

import com.kaibes.im.KaibesApplication;
import com.kaibes.im.R;
import com.kaibes.im.control.activity.KaibesActivity;
import com.kaibes.im.control.activity.MainActivity;
import com.kaibes.im.control.thread.ConnectThread;
import com.kaibes.im.model.data.ContactInformationData;
import com.kaibes.im.model.data.ContactsInformationData;
import com.kaibes.im.model.data.UserInformationData;
import com.kaibes.im.utils.ByteStringUtil;
import com.kaibes.im.utils.JsonParserUtil;
import com.kaibes.im.utils.StaticValuesUtil;
import com.kaibes.im.view.fragment.AllOnlineFragment;
import com.kaibes.im.view.fragment.KaibesFragment;
import com.kaibes.im.view.fragment.LoginFragment;
import com.kaibes.im.view.fragment.MainFragment;
import com.kaibes.im.view.fragment.SearchResultFragment;

public class SocketWorker {

    public static final int ACTION_MORE_SOCKET = 0;
    public static final int ACTION_REGISTERED = 1;
    public static final int ACTION_CHANGE_PASSWORD = 2;
    public static final int ACTION_LOGIN = 3;
    public static final int ACTION_USERINFO = 4;
    public static final int ACTION_CONTACTS = 5;
    public static final int ACTION_MESSAGE = 6;
    public static final int ACTION_CONTACTS_UPDATE = 7;
    public static final int ACTION_CONTACTS_INFO = 8;
    public static final int ACTION_FILE_INFO = 9;
    public static final int ACTION_CHANGE_USERINFO = 10;
    public static final int ACTION_CHANGE_REMARK = 11;
    public static final int ACTION_ADD_CONTACTS = 12;
    public static final int ACTION_REMOVE_CONTACTS = 13;
    public static final int ACTION_SEARCH = 14;
    public static final int ACTION_PUT_PHOTO = 15;
    public static final int ACTION_NOTIFICATION = 16;
    public static final int ACTION_USER_UNLOGIN = 17;
    // 测试用
    public static final int ACTION_USER_ONLINE = 99;

    public final static int notification_id = 0x1;
    public static SocketWorker instance = null;

    private KaibesApplication kaibesApplication = null;
    private ConnectThread connect = null;
    private HashMap<String, Integer> hashCount;

    private SocketWorker(KaibesApplication kaibesApplication,
	    ConnectThread connect) {
	hashCount = new HashMap<String, Integer>();
	this.kaibesApplication = kaibesApplication;
	this.connect = connect;
	kaibesApplication.setSocketWorker(this);
    }

    public static SocketWorker getInstance() {
	return instance;
    }

    public static void newInstance(KaibesApplication kaibesApplication,
	    ConnectThread connect) {
	instance = new SocketWorker(kaibesApplication, connect);
    }

    public void sendData(int head, Object action, Object... data) {
	JsonParserUtil jsonParserUtil = new JsonParserUtil();

	if (head == 0) {
	    // ActionCallbackModel
	    jsonParserUtil.newSelf().putValue("h", head).putValue("a", action)
		    .putValue("d", (String) data[0]);
	}

	if (head == 1) {
	    jsonParserUtil.newSelf().putValue("h", head).putValue("a", action)
		    .newJsonArraySon();
	    switch ((int) action) {
	    case SocketWorker.ACTION_REGISTERED:
		// RegisterFragment
		jsonParserUtil.newJsonObjectSon()
			.putJsonObjectSonValue("username", data[0])
			.putJsonObjectSonValue("password", data[1])
			.putJsonObjectSonValue("question", data[2])
			.putJsonObjectSonValue("answer", data[3])
			.addJSONObjectSon().addJsonArraySon("d");
		break;

	    case SocketWorker.ACTION_LOGIN:
		// LoginFragment
		jsonParserUtil.newJsonObjectSon()
			.putJsonObjectSonValue("username", data[0])
			.putJsonObjectSonValue("password", data[1])
			.addJSONObjectSon().addJsonArraySon("d");
		break;

	    case SocketWorker.ACTION_USERINFO:
		// ActionCallbackModel
		jsonParserUtil.newJsonObjectSon().addJSONObjectSon()
			.addJsonArraySon("d");
		break;

	    case SocketWorker.ACTION_CONTACTS:
		// MainFragment
		if (data.length < 1) {
		    jsonParserUtil.newJsonObjectSon().addJSONObjectSon()
			    .addJsonArraySon("d");
		} else {
		    jsonParserUtil.putValue("d", data[0]);
		}
		break;

	    case SocketWorker.ACTION_MESSAGE:
		// ChatFragment
		jsonParserUtil.newJsonObjectSon()
			.putJsonObjectSonValue("to", data[0])
			.putJsonObjectSonValue("message", data[1])
			.addJSONObjectSon().addJsonArraySon("d");
		break;

	    case SocketWorker.ACTION_CONTACTS_UPDATE:
		jsonParserUtil.newJsonObjectSon().addJSONObjectSon()
			.addJsonArraySon("d");
		break;

	    case SocketWorker.ACTION_CONTACTS_INFO:
		// ActionCallbackModel
		jsonParserUtil.putValue("d", data[0]);
		break;

	    case SocketWorker.ACTION_FILE_INFO:
		// KaibesApplication;ActionCallbackModel;ContactListviewAdapter;SearchResultListviewAdapter
		jsonParserUtil.newJsonArraySon().newJsonObjectSon()
			.putJsonObjectSonValue("username", data[0])
			.putJsonObjectSonValue("filename", data[1])
			.putJsonObjectSonValue("filefolder", data[2])
			.putJsonObjectSonValue("filesize", data[3])
			.addJSONObjectSon().addJsonArraySon("d");
		break;

	    case SocketWorker.ACTION_CHANGE_USERINFO:
		// UserInformationEditFragment
		jsonParserUtil.newJsonArraySon().putJsonArraySonValue(data[0])
			.addJsonArraySon("d");
		break;

	    case SocketWorker.ACTION_CHANGE_REMARK:
		jsonParserUtil.newJsonArraySon().newJsonObjectSon()
			.putJsonObjectSonValue("contactname", data[0])
			.putJsonObjectSonValue("remark", data[1])
			.addJSONObjectSon().addJsonArraySon("d");
		break;

	    case SocketWorker.ACTION_ADD_CONTACTS:
		// ContactInformationAddFragment
		jsonParserUtil.newJsonArraySon().newJsonObjectSon()
			.putJsonObjectSonValue("username", data[0])
			.putJsonObjectSonValue("contactname", data[1])
			.addJSONObjectSon().addJsonArraySon("d");
		break;

	    case SocketWorker.ACTION_REMOVE_CONTACTS:
		jsonParserUtil.newJsonArraySon().newJsonObjectSon()
			.putJsonObjectSonValue("contactname", data[0])
			.addJSONObjectSon().addJsonArraySon("d");
		break;

	    case SocketWorker.ACTION_SEARCH:
		// ContactAddFragment
		jsonParserUtil.newJsonArraySon().newJsonObjectSon()
			.putJsonObjectSonValue("username", data[0])
			.putJsonObjectSonValue("nickname", data[1])
			.putJsonObjectSonValue("sex", data[2])
			.putJsonObjectSonValue("birth_1", data[3])
			.putJsonObjectSonValue("birth_2", data[4])
			.addJSONObjectSon().addJsonArraySon("d");
		break;

	    case SocketWorker.ACTION_PUT_PHOTO:
		// UserInformationFragment
		jsonParserUtil.newJsonArraySon().newJsonObjectSon()
			.putJsonObjectSonValue("filename", data[0])
			.putJsonObjectSonValue("filefolder", data[1])
			.putJsonObjectSonValue("filesize", data[2])
			.addJSONObjectSon().addJsonArraySon("d");
		break;

	    case SocketWorker.ACTION_NOTIFICATION:
		// KaibesActivity
		jsonParserUtil.newJsonArraySon().newJsonObjectSon()
			.putJsonObjectSonValue("id", data[0])
			.putJsonObjectSonValue("choice", data[1])
			.addJSONObjectSon().addJsonArraySon("d");
		break;

	    case SocketWorker.ACTION_USER_UNLOGIN:
		// KaibesActivity
		jsonParserUtil.newJsonArraySon().newJsonObjectSon()
			.addJSONObjectSon().addJsonArraySon("d");
		break;

	    case SocketWorker.ACTION_USER_ONLINE:
		jsonParserUtil.newJsonObjectSon().addJSONObjectSon()
			.addJsonArraySon("d");
		break;

	    default:
		break;
	    }
	}

	if (connect.isConnected()) {
	    connect.sendMessageln(jsonParserUtil.toString());
	} else {
	    kaibesApplication.getCurrentActivity().getToastData().reset()
		    .setMessage("服务器未开启或者已经断开！");
	    kaibesApplication.getCurrentActivity().showToast();
	}

    }

    /**
     * 为什么要引入Task接口？ 因为这里包含了特殊的动作，如fragment界面隐藏增加替换等等，当activity处于后天时是不能进行这样的操作的，
     * 如果处于后太的activity被杀死，就更不能做了，所以将要做的事情保存在Task里，等activity处于前台时开始执行
     * 
     * @param
     * @author QiuShuiCai
     * @return void
     */
    @SuppressLint("NewApi")
    public void callBack(final String json) {
	JsonParserUtil jsonParserUtil = new JsonParserUtil(json);
	int head = (int) jsonParserUtil.getValue("h");
	Task task = null;

	if (head == 1) {
	    int action = (int) jsonParserUtil.getValue("a");
	    jsonParserUtil.setJsonArraySon("d");
	    switch (action) {

	    case SocketWorker.ACTION_REGISTERED: {
		final boolean result = (boolean) jsonParserUtil
			.getJsonObjectSonValue("result");
		final String msg = (String) jsonParserUtil
			.getJsonObjectSonValue("message");

		task = new Task() {
		    @Override
		    public void doWork() {
			KaibesActivity kaibesActivity = kaibesApplication
				.getCurrentActivity();
			kaibesActivity.getAlertDialogData().reset();
			if (result) {
			    kaibesActivity
				    .refresh(
					    KaibesFragment.LOGIN_FRAGMENT,
					    LoginFragment.REFRESH_USERNAME_PASSWORD_DEFAULT);
			    kaibesActivity.onBackPressed();
			    kaibesActivity.getAlertDialogData().setTitle(
				    "提示：注册成功！");

			} else {
			    kaibesActivity.getAlertDialogData().setTitle(
				    "提示：注册失败！");
			}
			kaibesActivity.getAlertDialogData().setMessage(msg);
			kaibesActivity.showAlertDialog();
		    }
		};

	    }
		break;

	    case SocketWorker.ACTION_CHANGE_PASSWORD: {
		// TODO 我打算把用户注册，修改密码这些和程序分开来，所以这里没有提供修改密码的方法
	    }
		break;

	    case SocketWorker.ACTION_LOGIN: {
		final Boolean result = (Boolean) jsonParserUtil
			.getJsonObjectSonValue("result");
		final String msg = (String) jsonParserUtil
			.getJsonObjectSonValue("message");

		task = new Task() {

		    @Override
		    public void doWork() {
			kaibesApplication.getCurrentActivity()
				.closeProgressDialog();

			if (result) {
			    if (kaibesApplication.isLoginAgain()) {
				kaibesApplication.sendData(1,
					SocketWorker.ACTION_CONTACTS);
			    } else {
				kaibesApplication
					.getCurrentActivity()
					.getProgressDialogData()
					.reset()
					.setTitle(
						kaibesApplication
							.getString(R.string.download))
					.setMessage(
						kaibesApplication
							.getString(R.string.downloading));
				kaibesApplication.getCurrentActivity()
					.showProgressDialog();

				kaibesApplication.sendData(1,
					SocketWorker.ACTION_USERINFO);
			    }
			    // 创建多线程监听，消耗资源，不推荐开启
			    // kaibesApplication.getConnectRunable()
			    // .createReaderRunable(9);
			} else {
			    kaibesApplication.getCurrentActivity()
				    .getAlertDialogData().setTitle("提示：登陆失败！")
				    .setMessage(msg);
			    kaibesApplication.getCurrentActivity()
				    .showAlertDialog();
			}
		    }
		};

	    }
		break;

	    case SocketWorker.ACTION_USERINFO: {
		kaibesApplication
			.setUserInformationData(new UserInformationData(
				jsonParserUtil.getJsonObjectSon()));
		Editor editor = kaibesApplication.getUserPreferences().edit();
		editor.putString(kaibesApplication.getUsername(),
			kaibesApplication.getUserInformationData().getPhoto());
		editor.commit();

		kaibesApplication.setUserPhotoPath(kaibesApplication
			.getUserInformationData().getPhoto());

		kaibesApplication.createDatabaseHelper();
		kaibesApplication.sendData(1, SocketWorker.ACTION_CONTACTS);
	    }
		break;

	    case SocketWorker.ACTION_CONTACTS: {
		JSONArray jsonArray = jsonParserUtil.getJsonArraySon();
		JSONArray jsonArraySend = new JSONArray();

		if (jsonArray.length() > 0) {
		    String[] contacts = new String[jsonArray.length()];
		    for (int i = 0; i < jsonArray.length(); i++) {
			try {
			    contacts[i] = ((JSONObject) (jsonArray.get(i)))
				    .getString("contactname");
			    boolean online = ((JSONObject) (jsonArray.get(i)))
				    .getBoolean("online");
			    if (kaibesApplication.isLoginAgain()) {
				kaibesApplication.getContactInformationData(
					contacts[i]).setOnline(online);
			    } else {
				if (online) {
				    kaibesApplication
					    .addContactFragmentDataHead(contacts[i]);
				    jsonArraySend.put(new JSONObject().put(
					    "contactname", contacts[i]));
				} else {
				    kaibesApplication
					    .addContactFragmentData(contacts[i]);
				    Cursor cursor = kaibesApplication
					    .getDatabaseHelper()
					    .getFriendInformationCursor(
						    "contactname = ?",
						    new String[] { contacts[i] });
				    if (cursor.getCount() == 0) {
					jsonArraySend.put(new JSONObject().put(
						"contactname", contacts[i]));
				    } else {
					kaibesApplication
						.addContactInformationData(new ContactInformationData(
							cursor, online));
				    }
				}
			    }
			} catch (JSONException e) {
			    e.printStackTrace();
			}
		    }

		    if (kaibesApplication.isLoginAgain()) {
			kaibesApplication.refresh(kaibesApplication
				.getCurrentActivity().getCurrentFragment(),
				KaibesFragment.REFRESH_FRAGMENT);
		    }

		    if (kaibesApplication.getContactFragmentDatasSize() > 0) {
			if (kaibesApplication.isLoginAgain()) {
			    kaibesApplication.setLoginAgain(false);
			} else {
			    if (jsonArraySend.length() > 0) {
				sendData(1, SocketWorker.ACTION_CONTACTS_INFO,
					jsonArraySend);
			    } else {
				task = getContactPhotoFromServer(contacts);
			    }
			}
		    }

		} else {
		    task = new Task() {

			@Override
			public void doWork() {
			    if (kaibesApplication.isLoginActivity()) {
				kaibesApplication.getCurrentActivity()
					.startActivityAndFinish(
						MainActivity.class);
			    }
			}
		    };
		}

	    }
		break;

	    case SocketWorker.ACTION_MESSAGE: {
		String from = (String) (jsonParserUtil
			.getJsonObjectSonValue("from"));
		String message = (String) (jsonParserUtil
			.getJsonObjectSonValue("message"));

		ContactInformationData contactInformationData = kaibesApplication
			.getContactInformationData(from);
		if (!kaibesApplication.getChatListviewDatas().contains(from)) {
		    kaibesApplication.addConversationFragmentData(from);
		}
		contactInformationData.addChatListviewData(message);

		if (isBackground()) {
		    if (kaibesApplication.getCurrentActivity() != null) {
			kaibesApplication
				.getCurrentActivity()
				.getIntent()
				.putExtra("notification",
					MainFragment.NOTIFICATION_MESSAGE);
		    }

		    kaibesApplication
			    .getCurrentActivity()
			    .getIntent()
			    .putExtra("contactname",
				    contactInformationData.getContactname());

		    PendingIntent pendingIntent = PendingIntent.getActivity(
			    kaibesApplication.getCurrentActivity(), 0,
			    kaibesApplication.getCurrentActivity().getIntent(),
			    PendingIntent.FLAG_UPDATE_CURRENT);

		    Notification notification = null;
		    if (Integer.valueOf(android.os.Build.VERSION.SDK) < 21) {
			NotificationCompat.Builder builder = new NotificationCompat.Builder(
				kaibesApplication.getCurrentActivity());
			notification = builder
				.setTicker(contactInformationData.getMessage())
				.setSmallIcon(R.drawable.ic_launcher)
				.setLargeIcon(
					kaibesApplication
						.getContactBitmap(contactInformationData
							.getPhoto()))
				.setContentTitle(
					contactInformationData.getContactname())
				.setContentText(
					contactInformationData.getMessage())
				.setAutoCancel(true)
				.setContentIntent(pendingIntent)
				.setSound(
					Uri.parse("android.resource://com.kaibes.im/raw/gm.mp3"))
				.setDefaults(Notification.DEFAULT_ALL).build();
		    } else {
			Notification.Builder builder = new Notification.Builder(
				kaibesApplication.getCurrentActivity());
			notification = builder
				.setSmallIcon(R.drawable.ic_launcher)
				.setLargeIcon(
					kaibesApplication
						.getContactBitmap(contactInformationData
							.getPhoto()))
				.setContentTitle(
					contactInformationData.getContactname())
				.setContentText(
					contactInformationData.getMessage())
				.setVisibility(Notification.VISIBILITY_PUBLIC)
				.setPriority(
					Notification.PARCELABLE_WRITE_RETURN_VALUE)
				.setAutoCancel(true)
				.setContentIntent(pendingIntent)
				.setSound(
					Uri.parse("android.resource://com.kaibes.im/raw/gm.mp3"))
				.setDefaults(Notification.DEFAULT_ALL).build();
		    }
		    NotificationManagerCompat manager = NotificationManagerCompat
			    .from(connect.getKaibesService());
		    manager.cancel(notification_id);
		    manager.notify(notification_id, notification);
		} else {
		    kaibesApplication.refresh(KaibesFragment.MAIN_FRAGMENT,
			    MainFragment.REFRESH_CONVERSATION);
		    if (kaibesApplication.getCurrentActivity()
			    .findFragmentByTag(KaibesFragment.CHAT_FRAGMENT) != null) {
			kaibesApplication.refresh(KaibesFragment.CHAT_FRAGMENT,
				1);
		    }
		    kaibesApplication.getSoundPoolUtil().play(0);
		}
	    }
		break;

	    case SocketWorker.ACTION_CONTACTS_UPDATE: {
		String contactname = (String) jsonParserUtil
			.setJsonArraySon("d").setJsonObjectSon(0)
			.getJsonObjectSonValue("contactname");
		Boolean online = (Boolean) jsonParserUtil
			.getJsonObjectSonValue("online");
		String photo = (String) jsonParserUtil
			.getJsonObjectSonValue("photo");

		if (kaibesApplication.getContactInformationData(contactname) != null) {
		    if (online != null) {
			kaibesApplication
				.getContactInformationData(contactname)
				.setOnline(online);
			if (kaibesApplication.getCurrentActivity() != null
				&& kaibesApplication.isMainActivity()) {
			    if (online) {
				kaibesApplication
					.moveContactFragment2Top(contactname);
				try {
				    sendData(1,
					    SocketWorker.ACTION_CONTACTS_INFO,
					    new JSONArray()
						    .put(new JSONObject().put(
							    "contactname",
							    contactname)));
				    kaibesApplication.getSoundPoolUtil().play(
					    16);
				} catch (JSONException e) {
				    // TODO Auto-generated catch block
				    e.printStackTrace();
				}
			    } else {
				kaibesApplication
					.moveContactFragment2End(contactname);
			    }
			}

		    } else if (photo != null) {
			kaibesApplication
				.getContactInformationData(contactname)
				.setPhoto(photo);

			int count = getPhotoFromServer(
				kaibesApplication.getContactFilesFolder(),
				kaibesApplication.getContactCacheFolder(),
				StaticValuesUtil.CONTACT_PHOTO, contactname,
				photo, 0);
			if (count != 0) {
			    hashCount
				    .put(StaticValuesUtil.CONTACT_PHOTO, count);
			}

		    } else {
			JSONObject js = jsonParserUtil.getJsonObjectSon();
			JSONArray ja = js.names();
			for (int i = 0; i < ja.length(); i++) {
			    try {
				String key = (String) ja.get(i);
				kaibesApplication.getContactInformationData(
					contactname).setValue(key,
					(String) js.get(key));
			    } catch (JSONException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			    }
			}
			kaibesApplication.refresh(KaibesFragment.MAIN_FRAGMENT,
				MainFragment.REFRESH_CONVERSATION);
			kaibesApplication.refresh(KaibesFragment.CHAT_FRAGMENT,
				KaibesFragment.REFRESH_FRAGMENT);
		    }

		    kaibesApplication.refresh(KaibesFragment.MAIN_FRAGMENT,
			    MainFragment.REFRESH_CONTACTS);
		}

	    }
		break;

	    case SocketWorker.ACTION_CONTACTS_INFO: {
		ContactsInformationData contactsInformationsData = new ContactsInformationData(
			jsonParserUtil.getJsonArraySon());

		String[] contacts = new String[contactsInformationsData
			.length()];

		for (int i = 0; i < contactsInformationsData.length(); i++) {

		    kaibesApplication
			    .getDatabaseHelper()
			    .replaceContactinformation(
				    new String[] {
					    contacts[i] = contactsInformationsData
						    .getContactname(i),
					    contactsInformationsData
						    .getNickname(i),
					    contactsInformationsData
						    .getPhoto(i),
					    contactsInformationsData.getSex(i),
					    contactsInformationsData
						    .getBirth(i),
					    contactsInformationsData
						    .getSignature(i),
					    contactsInformationsData
						    .getIntroduction(i),
					    contactsInformationsData.getJob(i),
					    contactsInformationsData
						    .getCompany(i),
					    contactsInformationsData
						    .getSchool(i),
					    contactsInformationsData
						    .getAddress(i),
					    contactsInformationsData
						    .getHometown(i),
					    contactsInformationsData
						    .getEmail(i),
					    contactsInformationsData
						    .getRemark(i) });

		    if (kaibesApplication
			    .getContactInformationData(contactsInformationsData
				    .getContactname(i)) != null) {
			ContactInformationData contactInformationData = kaibesApplication
				.getContactInformationData(contactsInformationsData
					.getContactname(i));
			contactInformationData.setData(contactsInformationsData
				.getData(i));
		    } else {
			kaibesApplication
				.addContactInformationData(contactsInformationsData
					.getContactInformationData(i));
		    }

		}

		task = getContactPhotoFromServer(contacts);
	    }
		break;

	    case SocketWorker.ACTION_FILE_INFO: {
		String filename = (String) jsonParserUtil
			.getJsonObjectSonValue("filename");
		int targetSize = (int) jsonParserUtil
			.getJsonObjectSonValue("targetSize");
		kaibesApplication.getKaibesFilesUtil().getKaibesFile(filename)
			.setTargetSize(targetSize);
	    }
		break;

	    case SocketWorker.ACTION_CHANGE_USERINFO: {
		final String message = (String) jsonParserUtil
			.getJsonObjectSonValue("message");
		task = new Task() {

		    @Override
		    public void doWork() {
			kaibesApplication.getCurrentActivity().getToastData()
				.reset().setMessage(message);
			kaibesApplication.getCurrentActivity().showToast();
		    }
		};
	    }
		break;

	    case SocketWorker.ACTION_CHANGE_REMARK: {
		final String message = (String) jsonParserUtil
			.getJsonObjectSonValue("message");
		task = new Task() {

		    @Override
		    public void doWork() {
			kaibesApplication.getCurrentActivity().getToastData()
				.reset().setMessage(message);
			kaibesApplication.getCurrentActivity().showToast();
		    }
		};
	    }
		break;

	    case SocketWorker.ACTION_ADD_CONTACTS: {
		final String message = (String) jsonParserUtil
			.getJsonObjectSonValue("message");
		task = new Task() {

		    @Override
		    public void doWork() {
			kaibesApplication.getCurrentActivity().getToastData()
				.reset().setMessage(message);
			kaibesApplication.getCurrentActivity().showToast();
		    }
		};
	    }
		break;
	    case SocketWorker.ACTION_REMOVE_CONTACTS: {
		final String contactname = (String) jsonParserUtil
			.getJsonObjectSonValue("contactname");
		final String message = (String) jsonParserUtil
			.getJsonObjectSonValue("message");

		task = new Task() {

		    @Override
		    public void doWork() {
			if (contactname == null) {
			    kaibesApplication.getCurrentActivity()
				    .getToastData().reset().setMessage(message);
			    kaibesApplication.getCurrentActivity().showToast();
			} else {
			    kaibesApplication
				    .removeContactFragmentData(contactname);
			}

			kaibesApplication.refresh(KaibesFragment.MAIN_FRAGMENT,
				MainFragment.REFRESH_CONTACTS);
			kaibesApplication.refresh(KaibesFragment.MAIN_FRAGMENT,
				MainFragment.REFRESH_CONVERSATION);
		    }
		};

	    }
		break;
	    case SocketWorker.ACTION_SEARCH: {
		if (jsonParserUtil.getJsonArraySon().length() > 0) {
		    ContactsInformationData contactsInformationsData = new ContactsInformationData(
			    jsonParserUtil.getJsonArraySon());
		    ArrayList<ContactInformationData> contactInformationDatas = new ArrayList<ContactInformationData>();

		    for (int i = 0; i < contactsInformationsData.length(); i++) {

			ContactInformationData contactInformationData = contactsInformationsData
				.getContactInformationData(i);

			if (contactInformationData.isOnline()) {
			    contactInformationDatas.add(0,
				    contactInformationData);
			} else {
			    contactInformationDatas.add(contactInformationData);
			}

		    }
		    kaibesApplication.getSearchDatas().clear();
		    kaibesApplication.getSearchDatas().addAll(0,
			    contactInformationDatas);
		    task = getSearchPhotoFromServer();
		} else {
		    kaibesApplication.getCurrentActivity()
			    .closeProgressDialog();
		    kaibesApplication.getCurrentActivity().getToastData()
			    .reset().setMessage("查找不到相关的用户。。。");
		    kaibesApplication.getCurrentActivity().showToast();
		}

	    }
		break;
	    case SocketWorker.ACTION_PUT_PHOTO: {
		final String filename = (String) jsonParserUtil
			.getJsonObjectSonValue("filename");
		final String message = (String) jsonParserUtil
			.getJsonObjectSonValue("message");

		if (message == null) {
		    int filesize = (int) jsonParserUtil
			    .getJsonObjectSonValue("filesize");

		    int size = 0;
		    if ((size = (int) (kaibesApplication.getUploadfiles()
			    .get(filename).length() - filesize)) > 8100) {
			size = 8100;
		    }

		    byte[] bs = new byte[size];
		    FileInputStream fis = null;
		    try {
			fis = new FileInputStream(kaibesApplication
				.getUploadfiles().get(filename));
			while (fis.read(bs, filesize, bs.length) != -1) {
			    sendData(0, filename,
				    ByteStringUtil.bytes2StringBase64(bs));
			    if (fis.available() != 0
				    && fis.available() < bs.length) {
				bs = new byte[fis.available()];
			    }
			}
			fis.close();
		    } catch (FileNotFoundException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		    } catch (IOException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		    }

		} else {
		    final String status = (String) jsonParserUtil
			    .getJsonObjectSonValue("status");

		    task = new Task() {

			@Override
			public void doWork() {
			    KaibesActivity kaibesActivity = kaibesApplication
				    .getCurrentActivity();
			    kaibesActivity.getAlertDialogData().reset()
				    .setTitle(filename).setMessage(message);
			    kaibesActivity.showAlertDialog();
			    // 文件上传完成，执行后续行为，如果有的话，这个行为通过callback完成
			    if (status != null) {
				upLoadFilecallBack(kaibesApplication
					.getUploadfiles().get(filename)
					.getParentFile().getParentFile()
					.getName()
					+ "_"
					+ kaibesApplication.getUploadfiles()
						.get(filename).getParentFile()
						.getName(), filename);
			    }
			}
		    };
		}

	    }
		break;

	    case SocketWorker.ACTION_NOTIFICATION: {
		NotificationInterpreter.explainClient(jsonParserUtil,
			kaibesApplication);
	    }
		break;

	    case SocketWorker.ACTION_USER_ONLINE: {
		if (jsonParserUtil.getJsonArraySon().length() > 0) {
		    ArrayList<String> names = new ArrayList<String>();
		    for (int i = 0; i < jsonParserUtil.getJsonArraySon()
			    .length(); i++) {
			try {
			    names.add(((JSONObject) jsonParserUtil
				    .getJsonArraySon().get(i))
				    .getString("contactname"));
			} catch (JSONException e) {
			    // TODO Auto-generated catch block
			    e.printStackTrace();
			}
		    }
		    kaibesApplication.allOnline = names;
		    kaibesApplication.changeFragment(AllOnlineFragment.class);
		    kaibesApplication.getCurrentActivity()
			    .closeProgressDialog();
		} else {
		    kaibesApplication.getCurrentActivity()
			    .closeProgressDialog();
		    kaibesApplication.getCurrentActivity().getToastData()
			    .reset().setMessage("查找不到相关的用户。。。");
		    kaibesApplication.getCurrentActivity().showToast();
		}
	    }
		break;

	    default:
		break;
	    }

	    if (task != null) {
		if (isBackground()) {
		    kaibesApplication.addTask(task);
		} else {
		    kaibesApplication.doWork(task);
		}
	    }
	}

	if (head == 0) {
	    String filename = (String) jsonParserUtil.getValue("a");
	    String data = (String) jsonParserUtil.getValue("d");

	    kaibesApplication.getKaibesFilesUtil().getKaibesFile(filename)
		    .write2File(data);

	    if (kaibesApplication.getKaibesFilesUtil().getKaibesFile(filename)
		    .isComplete()) {
		downLoadFilecallBack(kaibesApplication.getKaibesFilesUtil()
			.getKaibesFileAndRemoved(filename));

	    }

	}
    }

    private boolean isBackground() {
	ActivityManager activityManager = (ActivityManager) kaibesApplication
		.getSystemService(Context.ACTIVITY_SERVICE);
	List<RunningAppProcessInfo> appProcesses = activityManager
		.getRunningAppProcesses();

	for (RunningAppProcessInfo appProcess : appProcesses) {
	    if (appProcess.processName.equals(kaibesApplication
		    .getPackageName())
		    && (appProcess.importance == RunningAppProcessInfo.IMPORTANCE_SERVICE || appProcess.importance == RunningAppProcessInfo.IMPORTANCE_BACKGROUND)) {
		return true;
	    }
	}
	return false;
    }

    private Task getSearchPhotoFromServer() {
	kaibesApplication.getContactFilesFolder();

	Task task = null;

	if (getPhotoFromServer(StaticValuesUtil.SEARCH_PHOTO,
		kaibesApplication.getSearchDatas()) == 0) {
	    task = new Task() {

		@Override
		public void doWork() {
		    kaibesApplication
			    .changeFragment(SearchResultFragment.class);
		    kaibesApplication.getCurrentActivity()
			    .closeProgressDialog();
		}
	    };
	}

	return task;

    }

    private Task getContactPhotoFromServer(String[] contacts) {
	ArrayList<ContactInformationData> contactInformationDatas = new ArrayList<ContactInformationData>();
	for (int i = 0; i < contacts.length; i++) {
	    contactInformationDatas.add(kaibesApplication
		    .getContactInformationData(contacts[i]));
	}

	Task task = new Task() {

	    @Override
	    public void doWork() {
		if (kaibesApplication.isLoginActivity()) {
		    kaibesApplication.getCurrentActivity()
			    .startActivityAndFinish(MainActivity.class);
		} else {
		    kaibesApplication.refresh(KaibesFragment.MAIN_FRAGMENT,
			    MainFragment.REFRESH_CONTACTS);
		}
	    }
	};

	getPhotoFromServer(StaticValuesUtil.CONTACT_PHOTO,
		contactInformationDatas);

	return task;
    }

    private int getPhotoFromServer(File filesFolder, File cacheFolder,
	    String type, String contactname, String photoName, int count) {

	if (!photoName.equals(StaticValuesUtil.PHOTO_DEAFULT)) {
	    File photo = new File(filesFolder, StaticValuesUtil.PHOTO
		    + File.separator + photoName);

	    if (!photo.exists() || photo.length() < 1) {
		KaibesFile cachePhoto = new KaibesFile(cacheFolder,
			StaticValuesUtil.PHOTO + File.separator + photoName);
		kaibesApplication.getKaibesFilesUtil().addKabesFile(cachePhoto);
		cachePhoto.open().setType(type);

		sendData(1, SocketWorker.ACTION_FILE_INFO, contactname,
			photoName, StaticValuesUtil.PHOTO, cachePhoto.length());
		count++;
	    }
	}

	return count;
    }

    private int getPhotoFromServer(File filesFolder, File cacheFolder,
	    String type, ContactInformationData contactInformationData,
	    int count) {
	return getPhotoFromServer(filesFolder, cacheFolder, type,
		contactInformationData.getContactname(),
		contactInformationData.getPhoto(), count);
    }

    private int getPhotoFromServer(String type,
	    ArrayList<ContactInformationData> contactInformationDatas) {

	int count = 0;
	File filesFolder = kaibesApplication.getSearchCacheFolder();
	File cacheFolder = kaibesApplication.getSearchCacheFolder();

	if (type.equals(StaticValuesUtil.CONTACT_PHOTO)) {
	    filesFolder = kaibesApplication.getContactFilesFolder();
	    cacheFolder = kaibesApplication.getContactCacheFolder();
	}

	for (int i = 0; i < contactInformationDatas.size(); i++) {

	    count = getPhotoFromServer(filesFolder, cacheFolder, type,
		    contactInformationDatas.get(i), count);

	}

	if (count != 0) {
	    hashCount.put(type, count);
	}
	return count;
    }

    private void upLoadFilecallBack(String type, Object... objects) {
	// 文件上传好了要做什么?
	switch (type) {
	case StaticValuesUtil.USER_PHOTO: {
	    Editor editor = kaibesApplication.getUserPreferences().edit();
	    editor.putString(kaibesApplication.getUsername(),
		    (String) objects[0]);
	    editor.commit();
	}
	    break;

	default:
	    break;
	}
    }

    private void downLoadFilecallBack(KaibesFile kaibesFile, Object... objects) {
	// 文件下完了要做什么？
	switch (kaibesFile.getType()) {
	case StaticValuesUtil.USER_PHOTO: {
	    kaibesFile
		    .cacheRenameToFile(kaibesApplication.getUserFilesFolder());
	    kaibesApplication
		    .setUserPhotoBitmap(BitmapFactory
			    .decodeFile(kaibesApplication.getUserPhotoPath()
				    .getPath()));
	    kaibesApplication.refresh(KaibesFragment.MAIN_FRAGMENT,
		    MainFragment.REFRESH_USER_IMAGE_VIEW);
	}
	    break;

	case StaticValuesUtil.SEARCH_PHOTO: {
	    kaibesFile.close();
	    if (removeCount(kaibesFile.getType()) == 0) {
		kaibesApplication.changeFragment(SearchResultFragment.class);
		kaibesApplication.getCurrentActivity().closeProgressDialog();
	    }
	}
	    break;
	case StaticValuesUtil.CONTACT_PHOTO: {
	    kaibesFile.cacheRenameToFile(kaibesApplication
		    .getContactFilesFolder());
	    if (removeCount(kaibesFile.getType()) == 0) {
		if (kaibesApplication.isMainActivity()) {
		    kaibesApplication.refresh(KaibesFragment.MAIN_FRAGMENT,
			    MainFragment.REFRESH_CONTACTS);
		}
	    }
	}
	    break;

	default:
	    break;
	}
    }

    public interface Task {
	public void doWork();
    }

    private int removeCount(String type) {
	int count = hashCount.get(type);
	count--;
	hashCount.put(type, count);
	return count;
    }

}
